/*Author:S.Genikhov
Creatin Date: 14/08/2010
Last modified: 21/08/2010
Reviewed by :  K.Mogutin              at 21/08/2010

Version 1.
Server suppor only TCP connections.

Short project description:
Generic Server, work with the STATLESS Clients. Server possible to send and recive packets with
udefined length.
The protocol of determination of client packet lenght performs by Headerfunciton ,
supplied by application. After message completely recieved by server it will transef to application
both with header. There is no option the send HEADERLESS packets.
Identification of each client performs by identification handler (idClient), wich will
be supplyed by server to appropriate functions
*/

#ifndef __GENSERVER__
#define __GENSERVER__

#include <stdio.h>
#include <stdlib.h>

/*In Bellow list the prototypes of Callback function are given:
NewClientCb -   determined the application behavior on creation
NewMesssageCb - application behaviour when message arrived
NewExeptionCb - application behaviour when exeption arrived
ClientDiscnCb - application behaviour when client is disconnet durring
                reading or writing data trancaction, "_notfinished is
                the quantity of bytes that not transfered*/

typedef void (*NewClientCb)  (int _idClient,void* _app);
typedef void (*NewMesssageCb)(int _idClient,void* _app, void*  _buf,  size_t _mesSize);
typedef void (*NewExeptionCb)(int _idClient,void* _app, void*  _buf,  size_t _mesSize);
typedef void (*ClientDiscnCb)(int _idClient,void* _app, size_t _notreaded);

typedef struct GenericServer_t GenSv;
/*Returns pointer to server.
 _port - determnided by Application - Client protocol.
 Argument 2 void* _appdata - It is  data supplyed by applicatoin
 which can be used by Callback functions.
Arguments 3 and 4 - determined by Application - Client protocol and
used to evaluate the length of accepted messages from Clients.
Arguments 5-9 are the "CallBack" function has to be supplyed by user.
These function determined behaviour of server in different situations.
Argument _exptMessagSize is the constant size of OOB messages
determined by prococol. OOB messages sende to application
by NewExeptionCb  */

/*Returns valude of HeaderFunc is the  _headersize + message length,
 it has to be at least lenght of _headersize
 exaple:
 headersize == 4 bytes
 messasge - data pack from client to server
 messLength == 100 bytes
 char*  messageheader -is variable contains at least
 initial number of bytes from message == headersize
 leng = headerFunc(messageheader)
 leng ==104;*/
typedef size_t (*HeaderFunc)(void* _buffer,int _idclient,void* _appdata);
GenSv*  GsvServerNew(int _portTCP,int _portUDP,void* _appdata,int _headersize,
         HeaderFunc, NewClientCb,NewMesssageCb,ClientDiscnCb,
        size_t _exptMessagSize,NewExeptionCb);

/*Turns On Sever.
Return 0  if o.k. and err_Gsv if fails*/
int    GsvServerRun(GenSv* _this);

/*Copy messages from application to server buffers. These messges will be send to client.
If application had decide disconnect from clinet, all previously sent messages will be send before
disconnection will be done. Returns 0  if o.k. and 1 if fails.
The most possible reason of fails is memory allocation problem. In any case of errors happend
during sending, the corresponded client will be disconnected*/

int    GsvServerWrite(GenSv* _this,int _idClient, void* _buf,size_t _bufsize);

/*It the order to disconnect Client with correcsponded idClient
Disconnection not performs immidiatly but only after all previous
application messages would be delivered to a client*/
void   GsvServerDrop(GenSv*  _this, int _idClient);

/*Stop the Server activity, (opposite to Run). Before to "Stop" the server activity
 competele the all current action of read/write*/
void   GsvServerStop(GenSv*  _this);

void   GsvServerDelete(GenSv* _this);

/*Insert additionl Tasks to server according which can be activated periodically*/
typedef void (*ServerTaskfunc)(void* );
void GsvSchedullerAddTask(GenSv* _this, ServerTaskfunc _func,size_t period,void* data);


typedef enum err_Gsv
{
    GSV_SERVER_OK                           = 0,
    GSV_NEW_CLIENT_CONNECTION_PROBLEM       = 5,
    GSV_NEW_CLIENT_CREATION_PROBLEMS        = 10,
    GSV_NEW_CLIENT_INSERTION_PROBLEMS       = 15,
    GSV_ALLOCATION_READBUF_PROBLEM          = 20,
    GSV_SYSTEM_RECIEV_MESSAGE_PROB          = 25,
    GSV_SYSTEM_SEND_MESSAGE_PROB            = 30
} err_Gsv;

#endif /*__GENSERVER__*/
